#include "FpLogger.h"
#include <glog/logging.h>
//#include <stringapiset.h>

#if defined(_WIN32)
#include <direct.h>
#include <io.h>
#include <windows.h>
#elif
#include <unistd.h>
#endif

FPLOGGER_BEGIN

static int ToGLogLevel(const FpLogger::LogLevel& level) {
	int localLevel = 0;
	switch (level)
	{
	case FpLogger::LogLevel::LogLevel_INFO:
		localLevel = 0;
		break;
	case FpLogger::LogLevel::LogLevel_WARNING:
		localLevel = 1;
		break;
	case FpLogger::LogLevel::LogLevel_ERROR:
		localLevel = 2;
		break;
	default:
		break;
	}
}

GLoggerConfig::~GLoggerConfig()
{
	google::ShutdownGoogleLogging();
}

GLoggerConfig& GLoggerConfig::GetInstance()
{
	static GLoggerConfig loggerConfig;
	return loggerConfig;
}

GLoggerConfig::GLoggerConfig()
{
}

void GLoggerConfig::SetInitConfig(const std::string& topic, const std::string& logDir)
{
	google::InitGoogleLogging(topic.c_str());
	{
	#ifdef _WIN32
			int neededSize = MultiByteToWideChar(CP_UTF8, 0, logDir.c_str(), -1, 0, 0);
			wchar_t* wideCharString = new wchar_t[neededSize];
			MultiByteToWideChar(CP_UTF8, 0, logDir.c_str(), -1, wideCharString, neededSize);
			std::wstring wideString(wideCharString);
			delete[] wideCharString;
			wideCharString = NULL;
			_wmkdir(wideString.c_str());
	#else
			mkdir(logDir.c_str(), 0777);
	#endif // _WIN32
	}
	FLAGS_log_dir = logDir;
	std::string strPrefix = logDir + "\\" + topic + "-";
	google::SetLogDestination(google::GLOG_FATAL, "");
	google::SetLogDestination(google::GLOG_ERROR, "");
	google::SetLogDestination(google::GLOG_WARNING, "");
	google::SetLogDestination(google::GLOG_INFO, strPrefix.c_str());
	google::SetLogFilenameExtension(".log");
	FLAGS_logbufsecs = 0;
	FLAGS_alsologtostderr = true;
}

class FpLogger::Impl {
public:
	Impl(const char* file, int line, const FpLogger::LogLevel& level) {
		_logMsg = std::make_unique<google::LogMessage>(file, line, ToGLogLevel(level));
	};

	~Impl() = default;

	std::ostream& Stream() {
		return _logMsg->stream();
	}

private:
	friend class Logger;
	std::unique_ptr<google::LogMessage> _logMsg;
};

FpLogger::FpLogger(const char* file, int line, const LogLevel& level) : _impl(new Impl(file,line,level)),
_cfg(GLoggerConfig::GetInstance())
{
	
}

FpLogger::~FpLogger() = default;

std::ostream& FpLogger::Stream()
{
	if (!_ifInit.load())
	{
		std::cout << "Please Init Logger!!!"<<std::endl;
		return std::cerr;
	}
	return _impl->Stream();
}

void FpLogger::SetInitConfig(const std::string& topic, const std::string& logDir)
{
	_cfg.SetInitConfig(topic, logDir);
	if (!_ifInit.load())
	{
		_ifInit.store(true);
	}
}

FPLOGGER_END